/*
    UUID生成器
        产生一个uuid：32个的16进制数字字符串（16字节），由8个一字节随机数和一个单向增长的8字节序号组成
*/
#pragma once
#include <string>
#include <random>
#include <sstream>
#include <iomanip>
#include <atomic>

namespace ns_jsonrpc
{
    class UUID
    {
    public:
        static std::string uuid()
        {
            // 1.定义一个机器随机数生成器
            std::random_device rd;

            // 2.以机器随机数为种子，定义一个伪随机生成器
            std::mt19937 generator(rd()); // generator()生成的是一个32位的随机数

            // 3.定义限定数据范围的对象
            std::uniform_int_distribution<int> distribution(0, 255); // 用来控制随机数的范围

            // 4.生成8个一字节随机数，按照特定格式组织成为16进制数字字符串
            std::stringstream ss;
            for(int i = 0; i < 8; i++)
            {
                if (i == 4 || i == 6) 
                    ss << "-";
                ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
            }
            ss << "-";

            // 5.定义一个8字节的原子序号，逐字节组织成16进制数字字符串
            static std::atomic<size_t> seq(1); // 定义一个原子对象（静态是因为要单项增长）
            size_t res = seq.fetch_add(1); // 变量值加1
            for(int i = 7; i >= 0; i--)
            {
                if (i == 5) 
                    ss << "-";
                ss << std::setw(2) << std::setfill('0') << std::hex << ((res >> (i * 8)) & 0xff);
            }
            return ss.str();
        }
    };
}
